package racegame.extensions;

import handlers.RacersUpdate;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import com.smartfoxserver.v2.SmartFoxServer;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.Zone;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.entities.variables.ReservedRoomVariables;
import com.smartfoxserver.v2.extensions.SFSExtension;

public class RaceGameRoomExtension extends SFSExtension {

	public static final String CMD_RACERSUPDATE 		= "U";
	public static final String CMD_GAMEPLAYEVENTS		= "G";
	public static final String CMD_OFFTRACK	   			= "O";
	public static final String CMD_ADVANTAGE  			= "A";
	public static final String CMD_HEALTHCHECK 			= "H";
	public static final String PLAYER_NAME				= "pn";
	public static final String TIMESTAMP				= "T";
	public static final String PLAYER_STATUS			= "s";
	public static final String NUM_PLAYERS				= "n";
	
	public ISFSObject playersInfo = new SFSObject();
	public long startTime = 0;
	
	SmartFoxServer sfs;
	ScheduledFuture<?> taskScheduler;
	List<User> userList;
	int UPDATE_FREQUENCY = 100;
	int DELAY = 0;
	long currentTime = 0;
	
	Date now;
	
	@Override
	public void init() {
		// TODO Auto-generated method stub
		trace("Room extension created");
		
		addRequestHandler(CMD_RACERSUPDATE, RacersUpdate.class);
		
		sfs = SmartFoxServer.getInstance();
		taskScheduler = sfs.getTaskScheduler().scheduleAtFixedRate(new BroadcastTask(), DELAY, UPDATE_FREQUENCY, TimeUnit.MILLISECONDS);
		
	}
	
	private class BroadcastTask implements Runnable
	{
		public void run()
	    {		
			userList = getGameRoom().getUserList();
			
			// Only send extension responses when the race has begun
			if (playersInfo.size() > 0 ) { //&& (!getParentRoom().getVariable(ReservedRoomVariables.RV_GAME_STARTED).isNull()) 		    					
				// Add the offset from game creation to now to the object being broadcast
				now = new Date();
				currentTime = now.getTime() - startTime;
				playersInfo.putLong(TIMESTAMP, currentTime);
				
				// Send object containing all users latest received positions to all users in game room using TCP
				send(RaceGameRoomExtension.CMD_RACERSUPDATE, playersInfo,
						userList, true);
				
				// Cancel taskScheduler when room is empty
				if (userList.isEmpty())
				{
					taskScheduler.cancel(true);        			
				}
			} else {
				trace("Error ! Update is not send !! " + playersInfo );
			}
	    }
	}
	
	public Room getGameRoom()
	{
		return this.getParentRoom();
	}
	
	public Zone getZone()
	{
		return this.getParentZone();
	}

	@Override
	public void destroy() 
	{
		taskScheduler.cancel(true);
		super.destroy();
	}

}
















